#include "pluginmanager.h"

PluginManager::PluginManager(QObject *parent): QObject(parent){
	printf("construct pluginmanager\n");
}

void PluginManager::loadPlugins(QString dirPath){
	// static plugins
	foreach (QObject *plugin, QPluginLoader::staticInstances()){
		QFitsPlugin *qFitsPlugin = qobject_cast<QFitsPlugin *>(plugin);
		if (qFitsPlugin) // if it implements QFitsPlugin
			pluginList += plugin;
	}

	// dynamic plugins
	pluginsDir = QDir(dirPath);
#	if defined(Q_OS_WIN)
		if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
			pluginsDir.cdUp();
#	elif defined(Q_OS_MAC)
		if (pluginsDir.dirName() == "MacOS") {
			pluginsDir.cdUp();
			pluginsDir.cdUp();
			pluginsDir.cdUp();
		}
#	endif
	pluginsDir.cd("plugins");
	foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
		printf("file: %s %s\n", pluginsDir.absoluteFilePath(fileName).toLatin1().data(),
			fileName.toLatin1().data());
		QPluginLoader loader(pluginsDir.absoluteFilePath(fileName));
		QObject *plugin = loader.instance();
		if (plugin) {
			QFitsPlugin *qFitsPlugin = qobject_cast<QFitsPlugin *>(plugin);
			if (qFitsPlugin) // if it implements QFitsPluginInterface
				pluginList += plugin;
			else
				printf("  file %s DOES contain a valid plugin but not a QFitsPlugin: %s\n",
					fileName.toLatin1().data(), loader.errorString().toAscii().data());
		} else {
			printf("  file %s does NOT contain valid plugin: %s\n",
				fileName.toLatin1().data(), loader.errorString().toAscii().data());
		}

	}
}

void PluginManager::populateMenu( QMenu *menu ){
	foreach (QObject *plugin, pluginList)
		addToMenu(menu, plugin);
	if( menu->isEmpty() )
		menu->setEnabled(false);
	else
		menu->setEnabled(true);
}

/**
 * make a menu item and connect it with the activation slot
 */
void PluginManager::addToMenu(QMenu *menu, QObject *plugin){
	// dock the plugins
	QWidget *qWidget = qobject_cast<QWidget *>(plugin);
	QFitsPlugin *qFitsPlugin = qobject_cast<QFitsPlugin *>(plugin);
	if (plugin && qFitsPlugin && qWidget) {
		QDockWidget *dock = new QDockWidget(plugin->objectName(), qobject_cast<QWidget *>(parent()));
		dock->setAllowedAreas(Qt::TopDockWidgetArea | Qt::RightDockWidgetArea |
			Qt::BottomDockWidgetArea | Qt::LeftDockWidgetArea );
		dock->setWidget(qWidget); // reparents qWidget
		qobject_cast<QMainWindow *>(parent())->addDockWidget(Qt::TopDockWidgetArea, dock);
		QAction *action = dock->toggleViewAction();
		menu->addAction(action);
		qFitsPlugin->onInitialize(this);
		printf("object name: %s\n", plugin->objectName().toAscii().constData());
	} else
		printf("plugin \"%s\" failed to dock\n", plugin->objectName().toAscii().constData());
}

QString PluginManager::state(){
	QString s;
	foreach (QObject *plugin, pluginList){
	}
}
/*
void PluginManager::setGray(double midValue, double grayScale){
	printf("manager: setGray (%5.3f, %5.3f) from %lX\n", midValue, grayScale, (long unsigned)sender());
	// emit to all, including the sender
	emit grayChanged(midValue, grayScale);
}
*/

